module LiteBPU (
    input       clk,
    input       reset,

    input [31:0] inst,
    input [63:0] x1_value,
    input [63:0] xn_value,
    input [63:0] pc,
    output[4:0]  rxn,
    output [63:0] bpu_pc,
    output        bpu_taken,
    output        bpu_may_wait

);

wire        inst_jal;
wire        inst_jalr;
wire        inst_bxx;
// wire 
wire [2:0] func3;
wire [6:0] func7;
wire [4:0]  rs1;
wire [6:0]  op;
wire [63:0] I_imm;
wire [63:0] J_imm;
wire [63:0] U_imm;
wire [63:0] B_imm;
wire [63:0] jalr_src1;

wire        J_type;
wire        I_type;
wire        B_type;
wire [63:0] imm_src;
wire        rs1_x0;
wire        rs1_x1;
wire        rx1_xn;
wire        jalr_x0;
wire        jalr_x1;
wire        jalr_xn;


assign op   = inst[6:0];
assign func3= inst[14:12];
assign rs1  = inst[19:15];
assign func7= inst[31:25];
assign J_type       = inst_jal;
assign I_type       = inst_jalr;
assign B_type       = inst_bxx;

assign inst_jal     = op == 7'h6f;
assign inst_jalr    = op == 7'h67;
assign inst_bxx     = op == 7'h63 & func3 != 3'h2 & func3 != 3'h3;

assign rs1_x0       = rs1 == 5'h00;
assign rs1_x1       = rs1 == 5'h01;

assign jalr_x0      = inst_jalr & rs1_x0;
assign jalr_x1      = inst_jalr & rs1_x1;
assign jalr_xn      = inst_jalr & ~rs1_x1 & ~rs1_x0;
assign bpu_may_wait = jalr_xn;

assign J_imm        = {{44{inst[31]}},inst[19:12],inst[20],inst[30:21],1'b0};
assign I_imm        = {{53{inst[31]}},inst[30:20]};
assign B_imm        = {{52{inst[31]}},inst[7],inst[30:25],inst[11:8],1'b0};

assign imm_src  = ({64{J_type}}   & J_imm)
                | ({64{I_type}}   & I_imm)
                | ({64{B_type}}   & B_imm);
assign jalr_src1 =({64{jalr_x0}}   & 64'h0)
                | ({64{jalr_x1}}   & x1_value)
                | ({64{jalr_xn}}   & xn_value);
////
wire  [63:0] add_src1;
wire  [63:0] add_src2;

assign add_src1 = inst_jalr ? jalr_src1 : pc;
assign add_src2 = bpu_taken ? imm_src : 64'h4;
assign bpu_pc   = add_src1 + add_src2;
assign bpu_taken= inst_jal || inst_jalr || inst_bxx && inst[31]; 
               

endmodule
